package com.tqjc.execute.step;

import com.tqjc.area.entity.Roller;
import com.tqjc.area.entity.SteelPlate;
import com.tqjc.area.service.RollerService;
import com.tqjc.execute.cache.TaskStatus;
import com.tqjc.execute.cache.entity.WorkStatus;
import com.tqjc.execute.cache.service.CraneSteelCacheService;
import com.tqjc.execute.consts.WorkConst;
import com.tqjc.execute.exception.TaskRunningException;
import com.tqjc.execute.task.entity.Task;
import com.tqjc.execute.task.entity.TaskApart;
import com.tqjc.execute.task.service.impl.TaskApartServiceImpl;
import com.tqjc.execute.task.service.impl.TaskServiceImpl;
import com.tqjc.execute.utils.DateUtils;
import com.tqjc.execute.utils.HttpPLCUtils;
import com.tqjc.execute.utils.PlcOperator;
import com.tqjc.execute.work.CraneWorkFactory;
import com.tqjc.execute.work.callback.TaskCallback;
import com.tqjc.plccontrol.service.PointInfoService;
import com.tqjc.system.core.redis.TaskRedisApi;
import com.tqjc.system.core.util.SpringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;


@Slf4j
@Component
@Scope("prototype")
public class Suck2Step extends TaskApart implements TaskCallback {

    @Resource
    PlcOperator plcOperator;

    @Resource
    RollerService rollerService;

    @Resource
    PointInfoService pointInfoService;

    @Resource
    CraneWorkFactory craneWorkFactory;

    @Resource
    CraneSteelCacheService craneSteelCacheService;
    @Resource
    TaskStatus taskStatus;

    @Resource
    TaskRedisApi taskRedisApi;

    @Value("${server_host}")
    private String serverHost;

    @Autowired
    private RestTemplate restTemplate;


    public Suck2Step() {
        this.setType("suck2");
    }


    @Override
    public void onPreExecute() {
        try {
            setBeginTime(new Date());
            //设置工作状态
            WorkStatus status = taskStatus.getWorkStatusByCraneType(getCraneType());
            status.setNowStep(getType());
            status.setNowSteelNum(getTask().getSteelNo());
            status.setUnnormalStatus("");
            taskStatus.setWorkStatusByCraneType(getCraneType(), status);
        } catch (Exception e) {
            e.printStackTrace();
            log.error(getCraneType()+getType()+"前置出现异常", e);
        }


    }

    @Override
    public void onPostExecute() {
        try {
            setEndTime(new Date());

            //修改步骤状态
            WorkStatus status = taskStatus.getWorkStatusByCraneType(getCraneType());
            status.setNowStep("");
            status.setNowSteelNum("");
            taskStatus.setWorkStatusByCraneType(getCraneType(), status);

            getTask().setTaskStatus(1);
            SpringUtils.getBean(TaskServiceImpl.class).saveOrUpdate(getTask());
            SpringUtils.getBean(TaskApartServiceImpl.class).insert(this);

            //清除bean
            destroy();
        } catch (Exception e) {
            log.error(getCraneType()+ getType()+"后置出现异常",e);
            e.printStackTrace();
        }

    }

    @Override
    public void setTaskApartByTask(Task task) {
        this.setCallback(this);
        super.setTaskApartByTask(task);
    }

    /**
     * @param :
     * @return void
     * @author Patienyon
     * @description 不同任务独有执行方式
     * @date 2023/6/19 9:13
     */
    @Override
    public void customAction() throws TaskRunningException {
        try {
            String craneType = this.getTask().getCraneType();

            String steelNum= getTask().getSteelNo();
            this.setSteelNo(steelNum);
            /*Task task4Z= WorkConst.cacheTaskMap.get(craneType+"_task");
            Integer height=0;
            if(task4Z!=null){
                List<SteelPlate> steels=task4Z.getSteels4Offline();
                if("offline".equals(getTask().getType())){
                    //如果是suck多块，z轴要加上（已吸钢板-1）和要吸钢板的厚度
                    for(int i=1;i<steels.size();i++){ //吸第一块的高度在生成task时，就已经加到z轴上了，所以i从1开始；
                        height+= steels.get(i).getThickness();
                    }
                }
            }*/
            //清所有任务标志
            if("offline".equalsIgnoreCase(getTask().getType())){
                HttpPLCUtils.plcWritebcPlus(restTemplate,serverHost,craneType,"DB20.6.6",HttpPLCUtils.dataTypeList.get("bool"),"FALSE","下料标志A",false);
                HttpPLCUtils.plcWritebcPlus(restTemplate,serverHost,craneType,"DB20.6.7",HttpPLCUtils.dataTypeList.get("bool"),"FALSE","下料标志B",false);
                HttpPLCUtils.plcWritebcPlus(restTemplate,serverHost,craneType,"DB20.7",HttpPLCUtils.dataTypeList.get("bool"),"FALSE","下料标志C",false);
                HttpPLCUtils.plcWritebcPlus(restTemplate,serverHost,craneType,"DB20.7.1",HttpPLCUtils.dataTypeList.get("bool"),"FALSE","下料标志D",false);
            }else if("online".equalsIgnoreCase(getTask().getType())){
                HttpPLCUtils.plcWritebcPlus(restTemplate,serverHost,craneType,"DB20.6.2",HttpPLCUtils.dataTypeList.get("bool"),"FALSE","上料标志A",false);
                HttpPLCUtils.plcWritebcPlus(restTemplate,serverHost,craneType,"DB20.6.3",HttpPLCUtils.dataTypeList.get("bool"),"FALSE","上料标志B",false);
                HttpPLCUtils.plcWritebcPlus(restTemplate,serverHost,craneType,"DB20.6.4",HttpPLCUtils.dataTypeList.get("bool"),"FALSE","上料标志C",false);
                HttpPLCUtils.plcWritebcPlus(restTemplate,serverHost,craneType,"DB20.6.5",HttpPLCUtils.dataTypeList.get("bool"),"FALSE","上料标志D",false);
            }
            //写入半自动标志
            HttpPLCUtils.plcWritebcPlus(restTemplate,serverHost,craneType,"DB20.6.1",HttpPLCUtils.dataTypeList.get("bool"),"TRUE","半自动标志",false);

            //写入任务
            if("offline".equalsIgnoreCase(getTask().getType())){
                SteelPlate steelInfo=getTask().getSteel4OfflineCur();
                //写钢板信息给天车
                HttpPLCUtils.plcWritebcPlus(restTemplate,serverHost,craneType,"DB20.24",HttpPLCUtils.dataTypeList.get("int16"),steelInfo.getLength()+"","任务钢板长",false);
                HttpPLCUtils.plcWritebcPlus(restTemplate,serverHost,craneType,"DB20.26",HttpPLCUtils.dataTypeList.get("int16"),steelInfo.getWidth()+"","任务钢板宽",false);
                HttpPLCUtils.plcWritebcPlus(restTemplate,serverHost,craneType,"DB20.28",HttpPLCUtils.dataTypeList.get("int16"),steelInfo.getThickness()+"","任务钢板厚",false);

                HttpPLCUtils.plcWritebcPlus(restTemplate,serverHost,craneType,"DB20.6.7",HttpPLCUtils.dataTypeList.get("bool"),"TRUE","下料标志B",false);
            }else if("online".equalsIgnoreCase(getTask().getType())){
                HttpPLCUtils.plcWritebcPlus(restTemplate,serverHost,craneType,"DB20.6.3",HttpPLCUtils.dataTypeList.get("bool"),"TRUE","上料标志B",false);
            }
            //写入任务启动
            HttpPLCUtils.plcWritebcPlus(restTemplate,serverHost,craneType,"DB20.8.2",HttpPLCUtils.dataTypeList.get("bool"),"TRUE","任务启动",false);
            boolean isFinished = false;
            String isFinishStr="";
            Date startDate=new Date();
            while (!isFinished) {
                boolean overTime= DateUtils.isOverTimeByNow(startDate,100000);//超过100秒未完成，退出等待。
                if(overTime){
                    //log.error("等待{}天车半自动步骤2任务完成超时",getTask().getCraneType());
                    //throw new Exception("等待"+getTask().getCraneType()+"天车半自动步骤2任务完成超时");
                    WorkStatus status = taskStatus.getWorkStatusByCraneType(getCraneType());
                    status.setUnnormalStatus("等待任务完成超时");
                    taskStatus.setWorkStatusByCraneType(getCraneType(), status);
                    boolean isStartLogo= craneWorkFactory.getCraneWorkImpl(getCraneType()).getData().getSemiAutoRunFlag();
                    if(!isStartLogo){
                        break;
                    }
                }
                if("offline".equalsIgnoreCase(getTask().getType())){
                    isFinishStr= HttpPLCUtils.plcReadbc(restTemplate,serverHost,craneType,"下料B完成",false);
                }else if("online".equalsIgnoreCase(getTask().getType())){
                    isFinishStr= HttpPLCUtils.plcReadbc(restTemplate,serverHost,craneType,"上料B完成",false);
                }
                if ("true".equalsIgnoreCase(isFinishStr)) {
                    //清任务信号
                    if("offline".equalsIgnoreCase(getTask().getType())){
                        Roller roller= rollerService.getById(getTask().getRollerId());
                        String[] lockArr=roller.getLockSignal().split("-");
                        //清一级辊道锁定信号
                        HttpPLCUtils.plcWritebcPlus(restTemplate,serverHost,craneType,lockArr[1],HttpPLCUtils.dataTypeList.get("bool"),"FALSE",lockArr[0],true);
                        HttpPLCUtils.plcWritebcPlus(restTemplate,serverHost,craneType,"DB20.6.7",HttpPLCUtils.dataTypeList.get("bool"),"FALSE","下料标志B",false);
                    }else if("online".equalsIgnoreCase(getTask().getType())){
                        HttpPLCUtils.plcWritebcPlus(restTemplate,serverHost,craneType,"DB20.6.3",HttpPLCUtils.dataTypeList.get("bool"),"FALSE","上料标志B",false);
                    }
                    //清任务启动信号
                    HttpPLCUtils.plcWritebcPlus(restTemplate,serverHost,craneType,"DB20.8.2",HttpPLCUtils.dataTypeList.get("bool"),"FALSE","任务启动",false);
                    if("offline".equalsIgnoreCase(getTask().getType())){
                        //清下料B完成信号
                        HttpPLCUtils.plcWritebcPlus(restTemplate,serverHost,craneType,"DB20.7.7",HttpPLCUtils.dataTypeList.get("bool"),"FALSE","下料B完成",false);
                    }else if("online".equalsIgnoreCase(getTask().getType())){
                        //清上料B完成信号
                        HttpPLCUtils.plcWritebcPlus(restTemplate,serverHost,craneType,"DB20.7.3",HttpPLCUtils.dataTypeList.get("bool"),"FALSE","上料B完成",false);
                    }
                    isFinished = true;
                    log.info("PLC反馈{}天车半自动步骤2任务完成",getTask().getCraneType());
                }
            }
            WorkStatus status = taskStatus.getWorkStatusByCraneType(getTask().getCraneType());
            status.setUnnormalStatus("");
            taskStatus.setWorkStatusByCraneType(getCraneType(), status);
        } catch (Exception e) {
            WorkStatus status = taskStatus.getWorkStatusByCraneType(getCraneType());
            status.setUnnormalStatus(e.getMessage());
            taskStatus.setWorkStatusByCraneType(getCraneType(), status);
            throw new TaskRunningException(e.getMessage(), getTask().getCraneType());
        }
    }

    /**
     * @param :
     * @return void
     * @author Patienyon
     * @description 销毁Bean
     * @date 2023-06-28 10:41
     */
    @Override
    public void destroy() throws Exception {

    }

    /**
     * @param :
     * @return void
     * @author Patienyon
     * @description 初始化Bean
     * @date 2023-06-28 10:41
     */
    @Override
    public void afterPropertiesSet() throws Exception {

    }
}


